using System;
using System.Drawing;

namespace HslControls.GameSupport
{
	/// <summary>
	/// 经典的游戏引擎，实现基础的画布的绘制，定义基本的事件触发
	/// </summary>
	public class ClassicGameEngine
	{
		private int playerScore = 0;

		private bool isGameStart = false;

		private int widthOfItem = 20;

		private readonly int pixelCol = 0;

		private readonly int pixelRow = 0;

		private Bitmap bitmap = null;

		private Graphics graphics = null;

		/// <summary>
		/// 所有数据的合集
		/// </summary>
		protected ClassicGameItem[,] gameArrays = null;

		/// <summary>
		/// 获取游戏界面的列数据信息
		/// </summary>
		protected int PixelCol => pixelCol;

		/// <summary>
		/// 获取游戏界面的行数据信息
		/// </summary>
		protected int PixelRow => pixelRow;

		/// <summary>
		/// 需要显示数据的事件
		/// </summary>
		public event EventHandler<ClassicGameEventArgs> OnBitmapShowEvent;

		/// <summary>
		/// 实例化一个默认的对象
		/// </summary>
		public ClassicGameEngine(int pixelX, int pixelY)
		{
			pixelCol = pixelX;
			pixelRow = pixelY;
			gameArrays = new ClassicGameItem[pixelCol, pixelRow];
			for (int i = 0; i < pixelCol; i++)
			{
				for (int j = 0; j < pixelRow; j++)
				{
					gameArrays[i, j] = new ClassicGameItem();
				}
			}
			GameArrayAction(delegate(ClassicGameItem t)
			{
				t.ItemColor = Color.Black;
			});
			bitmap = new Bitmap(pixelCol * (widthOfItem + 1), pixelRow * (widthOfItem + 1));
			graphics = Graphics.FromImage(bitmap);
		}

		/// <summary>
		/// 循环操作当前的游戏的所有的点位
		/// </summary>
		/// <param name="action">操作的委托</param>
		public void GameArrayAction(Action<ClassicGameItem> action)
		{
			for (int i = 0; i < pixelCol; i++)
			{
				for (int j = 0; j < pixelRow; j++)
				{
					action(gameArrays[i, j]);
				}
			}
		}

		/// <summary>
		/// 复位游戏的所有的点位信息为没有东西
		/// </summary>
		public void GameArraysReset()
		{
			GameArrayAction(delegate(ClassicGameItem m)
			{
				m.HasItem = false;
			});
		}

		/// <summary>
		/// 复位或设置游戏的指定的列位信息为没有东西
		/// </summary>
		/// <param name="col">指定的列数据信息</param>
		/// <param name="hasItem">是否有点位信息</param>
		public void GameArraysColReset(int col, bool hasItem)
		{
			if (col >= 0 && col < pixelCol)
			{
				for (int i = 0; i < pixelRow; i++)
				{
					gameArrays[col, i].HasItem = hasItem;
				}
			}
		}

		/// <summary>
		/// 复位或设置游戏的指定的行位信息为没有东西
		/// </summary>
		/// <param name="row">指定的列数据信息</param>
		/// <param name="hasItem">是否有点位信息</param>
		public void GameArraysRowReset(int row, bool hasItem)
		{
			if (row >= 0 && row < pixelRow)
			{
				for (int i = 0; i < pixelCol; i++)
				{
					gameArrays[i, row].HasItem = hasItem;
				}
			}
		}

		/// <summary>
		/// 设置指定的点位数据为有对象
		/// </summary>
		/// <param name="points">点位数据信息</param>
		public void SetPointFixed(Point[] points)
		{
			for (int i = 0; i < points.Length; i++)
			{
				if (points[i].X >= 0 && points[i].X < pixelCol && points[i].Y >= 0 && points[i].Y < pixelRow)
				{
					gameArrays[points[i].X, points[i].Y].HasItem = true;
				}
			}
		}

		/// <summary>
		/// 设置指定的点位数据为有对象
		/// </summary>
		/// <param name="gameItem">活动对象信息</param>
		public void SetPointFixed(MoveGameItem gameItem)
		{
			if (gameItem != null)
			{
				Point[] points = gameItem.GetActualPoints();
				for (int i = 0; i < points.Length; i++)
				{
					if (points[i].X >= 0 && points[i].X < pixelCol && points[i].Y >= 0 && points[i].Y < pixelRow)
					{
						gameArrays[points[i].X, points[i].Y].HasItem = true;
						gameArrays[points[i].X, points[i].Y].ItemColor = gameItem.PaintColor;
					}
				}
			}
			else
			{
				Console.WriteLine("ClassicGameEngine:SetPointFixed:gameItem is NULL");
			}
		}

		/// <summary>
		/// 获取指定的行数据是否都是有物体的操作
		/// </summary>
		/// <param name="row">指定行索引</param>
		/// <returns>结果数据</returns>
		protected bool IsRowAllHasItem(int row)
		{
			for (int i = 0; i < PixelCol; i++)
			{
				if (!gameArrays[i, row].HasItem)
				{
					return false;
				}
			}
			return true;
		}

		/// <summary>
		/// 获取指定的行数据是否都是空的操作
		/// </summary>
		/// <param name="row">指定行索引</param>
		/// <returns>结果数据</returns>
		protected bool IsRowAllEmpty(int row)
		{
			for (int i = 0; i < PixelCol; i++)
			{
				if (gameArrays[i, row].HasItem)
				{
					return false;
				}
			}
			return true;
		}

		/// <summary>
		/// 获取指定的列数据是否都是有物体的操作
		/// </summary>
		/// <param name="col">指定列索引</param>
		/// <returns>结果数据</returns>
		protected bool IsColAllHasItem(int col)
		{
			for (int i = 0; i < PixelRow; i++)
			{
				if (!gameArrays[col, i].HasItem)
				{
					return false;
				}
			}
			return true;
		}

		/// <summary>
		/// 获取指定的列数据是否都是空的操作
		/// </summary>
		/// <param name="col">指定列索引</param>
		/// <returns>结果数据</returns>
		protected bool IsColAllEmpty(int col)
		{
			for (int i = 0; i < PixelRow; i++)
			{
				if (gameArrays[col, i].HasItem)
				{
					return false;
				}
			}
			return true;
		}

		/// <summary>
		/// 所有的数据信息下移一行，需要指定基础的行索引
		/// </summary>
		/// <param name="rowIndex">指定的行索引</param>
		protected void LinesMoveDown(int rowIndex)
		{
			for (int i = rowIndex; i < PixelRow; i++)
			{
				if (i < PixelRow - 1)
				{
					for (int k = 0; k < PixelCol; k++)
					{
						gameArrays[k, i].HasItem = gameArrays[k, i + 1].HasItem;
						gameArrays[k, i].ItemColor = gameArrays[k, i + 1].ItemColor;
						gameArrays[k, i].ItemCode = gameArrays[k, i + 1].ItemCode;
					}
				}
				else
				{
					for (int j = 0; j < PixelCol; j++)
					{
						gameArrays[j, i].HasItem = false;
					}
				}
			}
		}

		/// <summary>
		/// 绘制基本的游戏单元的，这个是最基本的单元
		/// </summary>
		/// <param name="g">绘图对象</param>
		/// <param name="x">坐标x</param>
		/// <param name="y">坐标y</param>
		protected void DrawGameItem(Graphics g, int x, int y)
		{
			if (x < 0 || x >= pixelCol || y < 0 || y >= pixelRow)
			{
				return;
			}
			int location_x = x * (widthOfItem + 1);
			int location_y = (pixelRow - y - 1) * (widthOfItem + 1);
			if (gameArrays[x, y].HasItem)
			{
				using Brush brush = new SolidBrush(gameArrays[x, y].ItemColor);
				g.FillRectangle(brush, new Rectangle(location_x, location_y, widthOfItem, widthOfItem));
				g.FillRectangle(Brushes.LightGray, new Rectangle(location_x + 2, location_y + 2, widthOfItem - 4, widthOfItem - 4));
				g.FillRectangle(brush, new Rectangle(location_x + widthOfItem / 4, location_y + widthOfItem / 4, widthOfItem / 2, widthOfItem / 2));
			}
			else
			{
				g.FillRectangle(Brushes.LightGray, new Rectangle(location_x, location_y, widthOfItem, widthOfItem));
				g.FillRectangle(Brushes.WhiteSmoke, new Rectangle(location_x + 2, location_y + 2, widthOfItem - 4, widthOfItem - 4));
				g.FillRectangle(Brushes.LightGray, new Rectangle(location_x + widthOfItem / 4, location_y + widthOfItem / 4, widthOfItem / 2, widthOfItem / 2));
			}
		}

		/// <summary>
		/// 使用指定的颜色绘制游戏坐标位置的界面
		/// </summary>
		/// <param name="g">绘制对象</param>
		/// <param name="x">坐标x</param>
		/// <param name="y">坐标y</param>
		/// <param name="color">指定绘制的颜色</param>
		protected void DrawGameItem(Graphics g, int x, int y, Color color)
		{
			if (x >= 0 && x < pixelCol && y >= 0 && y < pixelRow)
			{
				int location_x = x * (widthOfItem + 1);
				int location_y = (pixelRow - y - 1) * (widthOfItem + 1);
				using Brush brush = new SolidBrush(color);
				g.FillRectangle(brush, new Rectangle(location_x, location_y, widthOfItem, widthOfItem));
				g.FillRectangle(Brushes.LightGray, new Rectangle(location_x + 2, location_y + 2, widthOfItem - 4, widthOfItem - 4));
				g.FillRectangle(brush, new Rectangle(location_x + widthOfItem / 4, location_y + widthOfItem / 4, widthOfItem / 2, widthOfItem / 2));
			}
		}

		/// <summary>
		/// 使用指定的颜色绘制游戏坐标位置的界面
		/// </summary>
		/// <param name="g">绘制对象</param>
		/// <param name="points">数据点位信息</param>
		/// <param name="color">指定绘制的颜色</param>
		protected void DrawGameItem(Graphics g, Point[] points, Color color)
		{
			if (points != null)
			{
				for (int i = 0; i < points.Length; i++)
				{
					DrawGameItem(g, points[i].X, points[i].Y, color);
				}
			}
			else
			{
				Console.WriteLine("ClassicGameEngine:DrawGameItem:points is null");
			}
		}

		/// <summary>
		/// 使用指定的颜色绘制游戏坐标位置的界面
		/// </summary>
		/// <param name="g">绘制对象</param>
		/// <param name="gameItem">活动单元</param>
		protected void DrawGameItem(Graphics g, MoveGameItem gameItem)
		{
			if (gameItem != null)
			{
				DrawGameItem(g, gameItem.GetActualPoints(), gameItem.PaintColor);
			}
			else
			{
				Console.WriteLine("ClassicGameEngine:DrawGameItem:gameItem is null");
			}
		}

		/// <summary>
		/// 绘制所有的背景数据信息
		/// </summary>
		/// <param name="g">绘制对象</param>
		protected void DrawBackgroundImage(Graphics g)
		{
			for (int x = 0; x < pixelCol; x++)
			{
				for (int y = 0; y < pixelRow; y++)
				{
					DrawGameItem(g, x, y);
				}
			}
		}

		/// <summary>
		/// 等待重写实现的游戏逻辑部分
		/// </summary>
		/// <param name="g">绘制对象</param>
		protected virtual void DrawCustomer(Graphics g)
		{
		}

		/// <summary>
		/// 获取整个游戏的绘制信息
		/// </summary>
		/// <returns>游戏界面</returns>
		public Bitmap GetRenderBitmap()
		{
			graphics.Clear(SystemColors.Control);
			DrawBackgroundImage(graphics);
			DrawCustomer(graphics);
			return bitmap;
		}

		/// <summary>
		/// 触发一个事件，刷新结果显示
		/// </summary>
		/// <param name="bitmap">图片信息</param>
		protected void OnBitmapShow(Bitmap bitmap)
		{
			this.OnBitmapShowEvent?.Invoke(this, new ClassicGameEventArgs
			{
				RenderBitmap = bitmap
			});
		}

		/// <summary>
		/// 触发一个事件，刷新结果显示，获取默认的界面信息
		/// </summary>
		protected void OnBitmapShow()
		{
			this.OnBitmapShowEvent?.Invoke(this, new ClassicGameEventArgs
			{
				RenderBitmap = GetRenderBitmap()
			});
		}
	}
}
